package com.jcrj.service;

import com.jcrj.dao.DocDownDao;
import com.jcrj.dao.DocumentDao;
import com.jcrj.dao.FlowHistoryDao;
import com.jcrj.dao.FormDao;
import com.jcrj.entity.ODispatcherOrg;
import com.jcrj.entity.ODispatcherTop;
import com.jcrj.entity.ODocDown;
import com.jcrj.entity.ODocument;
import com.jcrj.entity.OFlowForm;
import com.jcrj.entity.OProcessHis;
import com.jcrj.entity.OProcessinstance;
import com.jcrj.entity.OUpdateHis;
import com.jcrj.entity.OUser;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.lob.SerializableBlob;
import org.textmining.text.extraction.WordExtractor;

public class DocumentFlowService {
	private DocumentDao documentDao;
	private FlowHistoryDao flowHistoryDao;
	private DocDownDao docDownDao;
	private WorkflowManagerService workflowManagerService;
	private FormDao formDao;
	private MailService mailService;

	public ODocument saveDocument(ODocument document, OUser user) {
		document.setDraftOrg(user.getOrgName());
		document.setDraftName(user.getName());
		document.setDraftUser(user.getId());
		this.documentDao.saveDocument(document);
		return document;
	}

	public ODocument updateDocument(ODocument document, OUser user) {
		document.setDraftName(user.getName());
		document.setDraftUser(user.getId());
		this.documentDao.updateDocument(document);
		return document;
	}

	public synchronized void saveDraftDocument(ODocument document, OUser user,
			int flowId, int nodeId, String executor, String message)
			throws Exception {
		Integer instanceId = this.workflowManagerService.createProssinstance(
				null, flowId, nodeId, executor, user.getId().intValue(),
				message, document.getTitle());
		document.setOpt("0");
		document.setDraftOrg(user.getOrgName());
		document.setDraftUser(user.getId());
		document.setDraftName(user.getName());
		document.setProcessId(instanceId);
		if ((document.getId() != null) && (!"".equals(document.getId())))
			this.documentDao.updateDocument(document);
		else {
			this.documentDao.saveDocument(document);
		}
		this.workflowManagerService.saveProssHis(instanceId.intValue(), nodeId,
				user, executor, "开始");
	}

	public synchronized void saveTransitionDocument(ODocument document,
			int flowId, int nodeId, String executor, OUser user, String message) {
		this.workflowManagerService.saveProssHis(document.getProcessId()
				.intValue(), nodeId, user, executor, "");
		Integer instanceId = this.workflowManagerService.createProssinstance(
				document.getProcessId().toString(), flowId, nodeId, executor,
				user.getId().intValue(), message, document.getTitle());
		document.setProcessId(instanceId);
		this.documentDao.updateDocument(document);
	}

	public synchronized void updateRejectDocument(ODocument doc, String status,
			OUser user, String message) {
		if ((doc != null) && (!"".equals(doc))) {
			String title = doc.getTitle() + "的公文被退回";
			String conent = doc.getTitle() + "的公文被" + user.getName() + "退回";
			if ("".equals(status)) {
				String hql = "delete from OProcessHis where processId="
						+ doc.getProcessId();
				this.documentDao.executeHql(hql);
				String hql1 = "delete from OProcessinstance where id="
						+ doc.getProcessId();
				this.documentDao.executeHql(hql1);
				doc.setDraftStaus("0");
				doc.setProcessId(null);
				this.mailService.saveSendInMail(title, conent, doc
						.getDraftUser().toString(), doc.getDraftName(), user);
			} else {
				String hql = "from OProcessHis where startNode=" + status
						+ " and processId=" + doc.getProcessId();
				List list = this.documentDao.findByHql(hql);
				if ((list != null) && (!list.isEmpty())) {
					OProcessHis his = (OProcessHis) list.get(0);
					this.mailService.saveSendInMail(title, conent, his
							.getExecutorId().toString(), his.getExecutor(),
							user);
					this.workflowManagerService.createProssinstance(doc
							.getProcessId().toString(), doc.getFlowId()
							.intValue(), Integer.parseInt(status), his
							.getExecutorId().toString(), user.getId()
							.intValue(), message, doc.getTitle());
					this.workflowManagerService.saveProssHis(doc.getProcessId()
							.intValue(), Integer.parseInt(status), user, his
							.getExecutorId().toString(), "退回");
				}
			}
			doc.setOverName("被" + user.getName() + "退回");
			doc.setReject("true");
			this.documentDao.updateDocument(doc);
		}
	}

	public List<ODocument> getDraftList(int userid, int currentPage,
			String status, String title, String startDate, String endDate) {
		String hql = "from ODocument o where o.draftUser=" + userid
				+ " and o.sfstatus=" + status + "and o.draftStaus=" + "0";
		if ((title != null) && (!"".equals(title.trim()))) {
			hql = hql + " and o.title like '%" + title + "%'";
		}
		if ((startDate != null) && (!"".equals(startDate.trim()))) {
			hql = hql + " and o.createTime >= to_date('" + startDate
					+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
		}
		if ((endDate != null) && (!"".equals(endDate.trim()))) {
			hql = hql + " and o.createTime <= to_date('" + endDate
					+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
		}
		hql = hql + "order by o.createTime desc,o.id desc";
		return this.documentDao.findByPage(hql, currentPage);
	}

	public void deleteDraftList(String[] ids) {
		if (ids != null) {
			String id = "";
			for (int i = 0; i < ids.length; i++) {
				if (id == "")
					id = id + ids[i];
				else {
					id = id + "," + ids[i];
				}
			}
			String hql = "delete from ODocument f where f.id in(" + id + ")";
			this.docDownDao.executeHql(hql);
		}
	}

	public Long countDraft(int userid, String status, String title,
			String startDate, String endDate) {
		String hql = "select count(*) from ODocument o where o.draftUser="
				+ userid + "and o.sfstatus=" + status + "and o.draftStaus="
				+ "0";
		if ((title != null) && (!"".equals(title.trim()))) {
			hql = hql + " and o.title like '%" + title + "%'";
		}
		if ((startDate != null) && (!"".equals(startDate.trim()))) {
			hql = hql + " and o.createTime >= to_date('" + startDate
					+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
		}
		if ((endDate != null) && (!"".equals(endDate.trim()))) {
			hql = hql + " and o.createTime <= to_date('" + endDate
					+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
		}
		return this.documentDao.countTotalByHql(hql);
	}

	public List<ODocument> getDocumentList(String process, int currentPage,
			String status, String title, String startDate, String endDate,
			String fwzh) {
		if ((process != null) && (!"".equals(process))) {
			String hql = "from ODocument f where f.processId in(" + process
					+ ")" + " and f.sfstatus=" + status;
			if ((title != null) && (!"".equals(title.trim()))) {
				hql = hql + "  and f.title like '%" + title + "%'";
			}
			if ((startDate != null) && (!"".equals(startDate.trim()))) {
				hql = hql + " and f.createTime >= to_date('" + startDate
						+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
			}
			if ((endDate != null) && (!"".equals(endDate.trim()))) {
				hql = hql + " and f.createTime <= to_date('" + endDate
						+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
			}
			if ((fwzh != null) && (!"".equals(fwzh))) {
				hql = hql
						+ " and concat(concat(f.postFont1,f.postFont2),f.postFont3) like '%"
						+ fwzh.trim() + "%'";
			}
			hql = hql + " order by f.createTime desc";
			return this.docDownDao.findByPage(hql, currentPage);
		}
		return null;
	}

	public List<ODocument> getAllDocumentList(String process, int count) {
		List faList = new ArrayList();
		if ((process != null) && (!"".equals(process))) {
			StringBuffer sql = new StringBuffer();
			String hql = "from OFlowForm";
			List<OFlowForm> oflowform = this.docDownDao.findByHql(hql);
			sql.append("select * from (select id,draft_org as unit,create_time as time,title,draft_name as name,sfstatus as fielTyoe,content_id as sort,flow_name as flow from o_Document where process_id in("
					+ process + ")");
			for (OFlowForm ff : oflowform) {
				sql.append(" union all select id,null,to_date(createtime,'yyyy-mm-dd'),null,TO_CHAR(USERID),flowid,null,TO_CHAR(flowid) from "
						+ ff.getTableName()
						+ " where instanceId in("
						+ process
						+ ") ");
			}
			sql.append(" ) t order by t.time desc");
			List<Object[]> listob = this.docDownDao.findListBySqlTop(
					sql.toString(), count);
			for (Object[] obj : listob) {
				ODocument od = new ODocument();
				od.setId(Integer.valueOf(((BigDecimal) obj[0]).intValue()));
				od.setBlqk(obj[2].toString());
				od.setTitle((String) obj[3]);
				od.setSfstatus((String) obj[5]);
				od.setBeizhu((String) obj[7]);
				faList.add(od);
			}
		}
		return faList;
	}

	private String listToString(List<OProcessinstance> list) {
		if ((list != null) && (!list.isEmpty())) {
			String id = "";
			for (int i = 0; i < list.size(); i++) {
				if (id == "")
					id = id + ((OProcessinstance) list.get(i)).getId();
				else {
					id = id + "," + ((OProcessinstance) list.get(i)).getId();
				}
			}
			return id;
		}
		return "";
	}

	public Long countMyDocument(String process, String status, String title,
			String startDate, String endDate, String fwzh) {
		if ((process != null) && (!"".equals(process))) {
			String hql = "select count(*) from ODocument f where f.processId in("
					+ process + ")" + " and f.sfstatus=" + status;
			if ((title != null) && (!"".equals(title.trim()))) {
				hql = hql + " and f.title like '%" + title + "%'";
			}
			if ((startDate != null) && (!"".equals(startDate.trim()))) {
				hql = hql + " and f.createTime >= to_date('" + startDate
						+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
			}
			if ((endDate != null) && (!"".equals(endDate.trim()))) {
				hql = hql + " and f.createTime <= to_date('" + endDate
						+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
			}
			if ((fwzh != null) && (!"".equals(fwzh))) {
				hql = hql
						+ " and concat(concat(f.postFont1,f.postFont2),f.postFont3) like '%"
						+ fwzh.trim() + "%'";
			}
			return this.docDownDao.countTotalByHql(hql);
		}
		return Long.valueOf(0L);
	}

	public void updateDocument(ODocument document) {
		this.documentDao.updateDocument(document);
	}

	public void saveUpdateHis(String name, int docId, String content) {
		OUpdateHis his = new OUpdateHis();
		his.setDocId(Integer.valueOf(docId));
		his.setUpdateTime(new Date());
		his.setUserName(name);
		his.setContent(content);
		this.documentDao.saveUpdateHis(his);
	}

	public List<OUpdateHis> getHisList(int docId) {
		String hql = "from OUpdateHis where docId=" + docId;
		return this.documentDao.findByHql(hql);
	}

	public ODocument getDocumentById(int id) {
		return (ODocument) this.documentDao.getObject(new ODocument(), id);
	}

	public ODocDown getDocDownById(int id) {
		return (ODocDown) this.documentDao.getObject(new ODocDown(), id);
	}

	public void updateDocDown(ODocDown doc) {
		this.docDownDao.updateDocDown(doc);
	}

	public String getInfoContent(String id) {
		String text = "";
		try {
			String sql = "select content from o_info_content where id=" + id;
			List list = this.documentDao.findBySql(sql);
			if ((list != null) && (!list.isEmpty())) {
				Blob blob = (Blob) list.get(0);
				InputStream in = blob.getBinaryStream();
				WordExtractor extrator = new WordExtractor();
				text = extrator.extractText(in);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	public SerializableBlob getContent(String contentId) throws IOException,
			SQLException {
		String sql = "select CONTENT from O_INFO_CONTENT where ID='"
				+ contentId + "'";
		@SuppressWarnings("rawtypes")
		List bs = documentDao.findBySql(sql);
		if ((bs != null) && (!bs.isEmpty())) {
			return (SerializableBlob) bs.get(0);
		}
		return null;
	}

	public List<ODocDown> findDocDownList(String title, String startDate,
			String endDate, String actorId, int currentPage, String look) {
		String hql = "from ODocDown o where  o.receiver=" + actorId
				+ " and o.isRead = " + look;
		if ((title != null) && (!"".equals(title))) {
			hql = hql + " and o.title like '%" + title.trim() + "%'";
		}
		if ((startDate != null) && (!"".equals(startDate.trim()))) {
			hql = hql + " and o.createTime >= to_date('" + startDate
					+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
		}
		if ((endDate != null) && (!"".equals(endDate.trim()))) {
			hql = hql + " and o.createTime <= to_date('" + endDate
					+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
		}
		hql = hql + " order by o.id desc";
		return this.docDownDao.findByPage(hql, currentPage);
	}

	public long getDocDownCount(String title, String startDate, String endDate,
			String actorId, int currentPage) {
		String hql = "select count(id) from ODocDown o where   o.receiver="
				+ actorId + " ";
		if ((title != null) && (!"".equals(title))) {
			hql = hql + " and o.title like '%" + title.trim() + "%'";
		}
		if ((startDate != null) && (!"".equals(startDate.trim()))) {
			hql = hql + " and o.createTime >= to_date('" + startDate
					+ " 00:00:00','yyyy-mm-dd hh24:mi:ss')";
		}
		if ((endDate != null) && (!"".equals(endDate.trim()))) {
			hql = hql + " and o.createTime <= to_date('" + endDate
					+ " 23:59:59','yyyy-mm-dd hh24:mi:ss')";
		}
		return this.docDownDao.countTotalByHql(hql).longValue();
	}

	public void saveDocDown(String[] userId, int docId, String stauts) {
		ODocument document = getDocumentById(docId);
		if ((userId != null) && (userId.length > 0))
			for (int i = 0; i < userId.length; i++) {
				ODocDown doc = new ODocDown();
				doc.setDocId(Integer.valueOf(docId));
				doc.setTitle(document.getTitle());
				doc.setReceiver(Integer.valueOf(Integer.parseInt(userId[i])));
				doc.setCreateTime(new Date());
				doc.setIsRead("0");
				doc.setType(stauts);
				this.docDownDao.saveDocDown(doc);
			}
	}

	public Long countMyDocument(List<OProcessinstance> list) {
		if (list != null) {
			String id = null;
			for (int i = 0; i < list.size(); i++) {
				if (id == "")
					id = ((OProcessinstance) list.get(i)).getId().toString();
				else {
					id = id + "," + ((OProcessinstance) list.get(i)).getId();
				}
			}
			String hql = "select count(*) from ODocument f where f.processId in("
					+ id + ")";
			return this.docDownDao.countTotalByHql(hql);
		}
		return Long.valueOf(0L);
	}

	public Long contDocDownList(String read, int userId) {
		String hql = "select count(id) from ODocDown where isRead = '" + read
				+ "' and receiver=" + userId;
		return this.documentDao.countTotalByHql(hql);
	}

	public List<ODispatcherTop> dispatcherTopList(String name, int currentPage) {
		String hql = "from ODispatcherTop ";
		if ((name != null) && (!"".equals(name))) {
			hql = hql + " where name like '%" + name.trim() + "%'";
		}
		return this.documentDao.findByPage(hql, currentPage);
	}

	public Long contDispatcherTop(String name) {
		String hql = "select count(id) from ODispatcherTop ";
		if ((name != null) && (!"".equals(name))) {
			hql = hql + " where name like '%" + name.trim() + "%'";
		}
		return this.documentDao.countTotalByHql(hql);
	}

	public void saveDispatcherTop(ODispatcherTop top, String ids, String names) {
		this.documentDao.saveDispatcherTop(top);
		if ((ids != null) && (!"".equals(ids))) {
			String[] orgids = ids.split(",");
			for (int i = 0; i < orgids.length; i++) {
				ODispatcherOrg org = new ODispatcherOrg();
				org.setOrgId(Integer.valueOf(Integer.parseInt(orgids[i])));
				org.setTopId(top.getId());
				this.documentDao.saveDispatcherOrg(org);
			}
		}
	}

	public void updateDispatcherTop(ODispatcherTop top, String ids, String names) {
		String hql = "delete from ODispatcherOrg where topId=" + top.getId();
		this.documentDao.executeHql(hql);
		this.documentDao.updateDispatcherTop(top);
		if ((ids != null) && (!"".equals(ids))) {
			String[] orgids = ids.split(",");
			for (int i = 0; i < orgids.length; i++) {
				ODispatcherOrg org = new ODispatcherOrg();
				org.setOrgId(Integer.valueOf(Integer.parseInt(orgids[i])));
				org.setTopId(top.getId());
				this.documentDao.saveDispatcherOrg(org);
			}
		}
	}

	public ODispatcherTop getDispatcherTop(int id) {
		return (ODispatcherTop) this.documentDao.getObject(
				new ODispatcherTop(), id);
	}

	public void deleteDispatcherTop(String[] ids) {
		if (ids != null) {
			String id = "";
			for (int i = 0; i < ids.length; i++) {
				if (id == "")
					id = id + ids[i];
				else {
					id = id + "," + ids[i];
				}
			}
			String hql = "delete from ODispatcherTop f where f.id in(" + id
					+ ")";
			this.documentDao.executeHql(hql);
			String hql1 = "delete from ODispatcherOrg where topId in (" + id
					+ ")";
			this.documentDao.executeHql(hql1);
		}
	}

	public List<ODispatcherTop> getDispatcherList(int orgId) {
		List list = this.workflowManagerService.getOrgAndParent(orgId);
		String hql = " from ODispatcherTop t where t.id in(select topId from ODispatcherOrg where orgId in(:list))";
		return this.documentDao.findListByName(hql, new String[] { "list" },
				new Object[] { list });
	}

	public String getDispatcherTopShort(String name) {
		String shortName = "";
		if ((name != null) && (!"".equals(name))) {
			String hql = "select shortName from ODispatcherTop where name='"
					+ name.trim() + "'";
			List list = this.documentDao.findByHql(hql);
			if ((list != null) && (!list.isEmpty())) {
				shortName = (String) list.get(0);
			}
		}
		return shortName;
	}

	public String getMaxTop(String name, String date, String status) {
		String maxTop = "";
		if ((name != null) && (!"".equals(name)) && (date != null)
				&& (!"".equals(date))) {
			String hql = "";
			if ("1".equals(status))
				hql = "select max(to_number(postFront3)) from O_Document where top='"
						+ name
						+ "' and postFront2='"
						+ date
						+ "' and sfstatus='" + status + "'";
			else {
				hql = "select max(to_number(postFront3)) from O_Document where postFront1='"
						+ name
						+ "' and postFront2='"
						+ date
						+ "' and sfstatus='" + status + "'";
			}

			List list = this.documentDao.findBySql(hql);
			if ((list != null) && (!list.isEmpty())) {
				BigDecimal num = (BigDecimal) list.get(0);
				if ((num != null) && (!"".equals(num)))
					maxTop = "" + num.intValue() + 1;
				else
					maxTop = "1";
			} else {
				maxTop = "1";
			}
		}
		return maxTop;
	}

	public void deleteOverFlow(String[] ids) {
		for (int i = 0; i < ids.length; i++) {
			ODocument doc = getDocumentById(Integer.parseInt(ids[i]));
			String hql = "delete from OProcessinstance where id="
					+ doc.getProcessId();
			this.documentDao.executeHql(hql);
			String hisHql = "delete from OProcessHis where  processId="
					+ doc.getProcessId();
			this.documentDao.executeHql(hisHql);
			if ((doc.getContentId() != null)
					&& (!"".equals(doc.getContentId()))) {
				String contenthql = "delete from OInfoContent where id='"
						+ doc.getContentId() + "'";
				this.documentDao.executeHql(contenthql);
				String noticeHql = "delete from ONotice where contentId='"
						+ doc.getContentId() + "'";
				this.documentDao.executeHql(noticeHql);
			}
			this.documentDao.deleteDocument(doc);
		}
	}

	public void deleteDocDown(String[] ids) {
		if (ids != null) {
			String id = "";
			for (int i = 0; i < ids.length; i++) {
				if (id == "")
					id = id + ids[i];
				else {
					id = id + "," + ids[i];
				}
			}
			String hql = "delete from ODocDown where id in(" + id + ")";
			this.docDownDao.executeHql(hql);
		}
	}

	public List<ODocDown> findDocDownListByDoc(int docId) {
		String sql = "select u.name,o.is_read from O_Doc_Down o,o_user u where u.id=o.receiver and o.doc_Id="
				+ docId + " order by is_Read desc";
		List<Object[]> list = this.docDownDao.findBySql(sql);
		List<ODocDown> docList = new ArrayList<ODocDown>();
		for (Object[] obj : list) {
			ODocDown doc = new ODocDown();
			doc.setName(obj[0].toString());
			doc.setIsRead(obj[1].toString());
			docList.add(doc);
		}
		return docList;
	}

	public DocumentDao getDocumentDao() {
		return this.documentDao;
	}

	public void setDocumentDao(DocumentDao documentDao) {
		this.documentDao = documentDao;
	}

	public FlowHistoryDao getFlowHistoryDao() {
		return this.flowHistoryDao;
	}

	public void setFlowHistoryDao(FlowHistoryDao flowHistoryDao) {
		this.flowHistoryDao = flowHistoryDao;
	}

	public DocDownDao getDocDownDao() {
		return this.docDownDao;
	}

	public void setDocDownDao(DocDownDao docDownDao) {
		this.docDownDao = docDownDao;
	}

	public WorkflowManagerService getWorkflowManagerService() {
		return this.workflowManagerService;
	}

	public void setWorkflowManagerService(
			WorkflowManagerService workflowManagerService) {
		this.workflowManagerService = workflowManagerService;
	}

	public FormDao getFormDao() {
		return this.formDao;
	}

	public void setFormDao(FormDao formDao) {
		this.formDao = formDao;
	}

	public MailService getMailService() {
		return this.mailService;
	}

	public void setMailService(MailService mailService) {
		this.mailService = mailService;
	}
}

/*
 * Location: /Volumes/work/oa/WEB-INF/classes/ Qualified Name:
 * com.jcrj.service.DocumentFlowService JD-Core Version: 0.6.0
 */